home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / entrylist.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  13KB  |  465 lines

  1. /*
  2.  * entrylist.c  V3.1
  3.  *
  4.  * Class for TM dock entries list
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. static const char *TextColumnExec;
  20. static const char *TextColumnImage;
  21. static const char *TextColumnSound;
  22.  
  23. /* EntryList class instance data */
  24. struct EntryListClassData {
  25.  struct Hook elcd_Construct;
  26. };
  27. #define TYPED_INST_DATA(cl, o) ((struct EntryListClassData *) INST_DATA((cl), (o)))
  28.  
  29. /* EntryList class construct function */
  30. #undef  DEBUGFUNCTION
  31. #define DEBUGFUNCTION EntryListClassConstruct
  32. __geta4 static ULONG EntryListClassConstruct(__a0 struct Hook *h,
  33.                                              __a1 struct DockEntry *de)
  34. {
  35.  /* Duplicate dock entry */
  36.  return((ULONG) CopyDockEntry(de, (Object *) h->h_Data));
  37. }
  38.  
  39. /* EntryList class destruct function */
  40. #undef  DEBUGFUNCTION
  41. #define DEBUGFUNCTION EntryListClassDestruct
  42. __geta4 static void EntryListClassDestruct(__a1 struct DockEntry *de)
  43. {
  44.  /* Free dock entry */
  45.  FreeDockEntry(de);
  46. }
  47.  
  48. /* EntryList class display function */
  49. #undef  DEBUGFUNCTION
  50. #define DEBUGFUNCTION EntryListClassDisplay
  51. __geta4 static void EntryListClassDisplay(__a1 struct DockEntry *de,
  52.                                           __a2 const char **array)
  53. {
  54.  /* Entry valid? */
  55.  if (de) {
  56.  
  57.   /* Yes, get object names. Get Exec object name */
  58.   if (de->de_Exec)
  59.    GetAttr(TMA_Name, de->de_Exec->ad_Object,  (ULONG *) array++);
  60.   else
  61.    *array++ = TextGlobalEmpty;
  62.  
  63.   /* Get Image object name */
  64.   if (de->de_Image)
  65.    GetAttr(TMA_Name, de->de_Image->ad_Object, (ULONG *) array++);
  66.   else
  67.    *array++ = TextGlobalEmpty;
  68.  
  69.   /* Get Sound object name */
  70.   if (de->de_Sound)
  71.    GetAttr(TMA_Name, de->de_Sound->ad_Object, (ULONG *) array);
  72.   else
  73.    *array = TextGlobalEmpty;
  74.  
  75.  } else {
  76.  
  77.   /* No, create title column */
  78.   *array++ = TextColumnExec;
  79.   *array++ = TextColumnImage;
  80.   *array   = TextColumnSound;
  81.  }
  82. }
  83.  
  84. /* Hooks */
  85. static const struct Hook DestructHook = {
  86.  {NULL, NULL}, (void *) EntryListClassDestruct, NULL, NULL
  87. };
  88. static const struct Hook DisplayHook = {
  89.  {NULL, NULL}, (void *) EntryListClassDisplay, NULL, NULL
  90. };
  91.  
  92. /* EntryList class method: OM_NEW */
  93. #undef  DEBUGFUNCTION
  94. #define DEBUGFUNCTION EntryListClassNew
  95. static ULONG EntryListClassNew(Class *cl, Object *obj, struct opSet *ops)
  96. {
  97.  ENTRYLIST_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  98.                 PrintTagList(ops->ops_AttrList)))
  99.  
  100.  /* Create object */
  101.  if (obj = (Object *) DoSuperNew(cl, obj,
  102.                                  MUIA_List_DestructHook, &DestructHook,
  103.                                  MUIA_List_DisplayHook,  &DisplayHook,
  104.                                  MUIA_List_Format,       "BAR,BAR,",
  105.                                  MUIA_List_DragSortable, TRUE,
  106.                                  MUIA_List_Title,        TRUE,
  107.                                  TAG_MORE,               ops->ops_AttrList)) {
  108.   struct EntryListClassData *elcd = TYPED_INST_DATA(cl, obj);
  109.   struct DockEntry          *de   = (struct DockEntry *)
  110.                                      GetHead((struct MinList *)
  111.                                               GetTagData(TMA_Entries, NULL,
  112.                                                          ops->ops_AttrList));
  113.  
  114.   /* Initialize construct hook */
  115.   elcd->elcd_Construct.h_Entry = (void *) EntryListClassConstruct;
  116.   elcd->elcd_Construct.h_Data  = obj;
  117.  
  118.   /* Set construct hook */
  119.   SetAttrs(obj, MUIA_List_ConstructHook, &elcd->elcd_Construct, TAG_DONE);
  120.  
  121.   /* For each dock entry */
  122.   while (de) {
  123.  
  124.    /* Insert entry */
  125.    DoMethod(obj, MUIM_List_InsertSingle, de, MUIV_List_Insert_Bottom);
  126.  
  127.    /* Next entry */
  128.    de = (struct DockEntry *) GetSucc((struct MinNode *) de);
  129.   }
  130.  }
  131.  
  132.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", obj))
  133.  
  134.  /* Return pointer to created object */
  135.  return((ULONG) obj);
  136. }
  137.  
  138. /* EntryList class method: MUIM_DragQuery */
  139. #undef  DEBUGFUNCTION
  140. #define DEBUGFUNCTION EntryListClassDragQuery
  141. static ULONG EntryListClassDragQuery(Class *cl, Object *obj,
  142.                                      struct MUIP_DragQuery *mpdq)
  143. {
  144.  ULONG rc = MUIV_DragQuery_Accept;
  145.  
  146. #if DEBUG_VERY_NOISY
  147.  /* This just generates too much debug output... */
  148.  ENTRYLIST_LOG(LOG2(Arguments, "Object 0x%08lx Source 0x%08lx", obj,
  149.                     mpdq->obj))
  150. #endif
  151.  
  152.  /* Is source our list? */
  153.  if (mpdq->obj != obj) {
  154.   Object *active;
  155.   ULONG   type   = TMOBJTYPES;
  156.  
  157.   /* No, get active entry */
  158.   if (GetAttr(TMA_Active, mpdq->obj, (ULONG *) &active))
  159.  
  160.    /* Get type of object */
  161.    GetAttr(TMA_Type, active, &type);
  162.  
  163.   /* Check type, only Exec, Image and Sound objects are accepted */
  164.   if (type > TMOBJTYPE_SOUND) rc = MUIV_DragQuery_Refuse;
  165.  }
  166.  
  167.  return(rc);
  168. }
  169.  
  170. /* EntryList class method: MUIM_DragDrop */
  171. #undef  DEBUGFUNCTION
  172. #define DEBUGFUNCTION EntryListClassDragDrop
  173. static ULONG EntryListClassDragDrop(Class *cl, Object *obj,
  174.                                     struct MUIP_DragDrop *mpdd)
  175. {
  176.  /* Is source our list? */
  177.  if (obj == mpdd->obj)
  178.  
  179.   /* Yes, call SuperClass */
  180.   DoSuperMethodA(cl, obj, (Msg) mpdd);
  181.  
  182.  else {
  183.   Object           *active;
  184.   ULONG             type;
  185.   ULONG             entry;
  186.   struct DockEntry *de;
  187.  
  188.   /* No, get active entry */
  189.   GetAttr(TMA_Active, mpdd->obj, (ULONG *) &active);
  190.  
  191.   ENTRYLIST_LOG(LOG1(Object, "0x%08lx", active))
  192.  
  193.   /* Get type of object */
  194.   GetAttr(TMA_Type, active, &type);
  195.  
  196.   ENTRYLIST_LOG(LOG1(Type, "%ld", type))
  197.  
  198.   /* Get drop mark */
  199.   GetAttr(MUIA_List_DropMark, obj, &entry);
  200.  
  201.   ENTRYLIST_LOG(LOG1(Drop Mark, "%ld", entry))
  202.  
  203.   /* Get entry corresponding to drop mark */
  204.   DoMethod(obj, MUIM_List_GetEntry, entry, &de);
  205.  
  206.   /* Entry valid? */
  207.   if (de) {
  208.  
  209.    ENTRYLIST_LOG(LOG1(Dock Entry, "0x%08lx", de))
  210.  
  211.    /* Which type? */
  212.    switch (type) {
  213.     case TMOBJTYPE_EXEC:
  214.      /* Detach old Exec object */
  215.      if (de->de_Exec) DoMethod(de->de_Exec->ad_Object, TMM_Detach,
  216.                                de->de_Exec);
  217.  
  218.      /* Attach new Exec object */
  219.      de->de_Exec = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  220.      break;
  221.  
  222.     case TMOBJTYPE_IMAGE:
  223.      /* Detach old Image object */
  224.      if (de->de_Image) DoMethod(de->de_Image->ad_Object, TMM_Detach,
  225.                                 de->de_Image);
  226.  
  227.      /* Attach new Image object */
  228.      de->de_Image = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  229.      break;
  230.  
  231.     case TMOBJTYPE_SOUND:
  232.      /* Detach old Sound object */
  233.      if (de->de_Sound) DoMethod(de->de_Sound->ad_Object, TMM_Detach,
  234.                                 de->de_Sound);
  235.  
  236.      /* Attach new Sound object */
  237.      de->de_Sound = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  238.      break;
  239.    }
  240.  
  241.    /* Redraw entry */
  242.    DoMethod(obj, MUIM_List_Redraw, entry);
  243.  
  244.   } else {
  245.    struct DockEntry  de;
  246.    struct AttachData ad;
  247.  
  248.    /* Initialize dummy entry */
  249.    de.de_Exec  = NULL;
  250.    de.de_Image = NULL;
  251.    de.de_Sound = NULL;
  252.  
  253.    /* Initialize dummy attach data */
  254.    ad.ad_Object = active;
  255.  
  256.    /* Set dummy attach data to correct type */
  257.    switch (type) {
  258.     case TMOBJTYPE_EXEC:  de.de_Exec  = &ad; break;
  259.     case TMOBJTYPE_IMAGE: de.de_Image = &ad; break;
  260.     case TMOBJTYPE_SOUND: de.de_Sound = &ad; break;
  261.    }
  262.  
  263.    /* Insert "dummy" entry (it will be duplicated!) */
  264.    DoMethod(obj, MUIM_List_InsertSingle, &de, MUIV_List_Insert_Bottom);
  265.  
  266.    ENTRYLIST_LOG(LOG0(Creating new entry))
  267.   }
  268.  }
  269.  
  270.  /* Return 1 to indicate that the method is implemented */
  271.  return(1);
  272. }
  273.  
  274. /* EntryList class method: TMM_Notify */
  275. #undef  DEBUGFUNCTION
  276. #define DEBUGFUNCTION EntryListClassNotify
  277. static ULONG EntryListClassNotify(Class *cl, Object *obj,
  278.                                   struct TMP_Notify *tmpn)
  279. {
  280.  ENTRYLIST_LOG(LOG1(Type, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  281.  
  282.  /* Object deleted? */
  283.  if (tmpn->tmpn_Data->ad_Object == NULL) {
  284.   int               i  = 0;
  285.   struct DockEntry *de;
  286.  
  287.   /* For each entry in list */
  288.   do {
  289.  
  290.    /* Get next entry */
  291.    DoMethod(obj, MUIM_List_GetEntry, i++, &de);
  292.  
  293.    ENTRYLIST_LOG(LOG1(Next entry, "0x%08lx", de))
  294.  
  295.    /* Try to remove attached object. Leave loop if object found */
  296.    if (de && RemoveDockEntryAttach(de, tmpn->tmpn_Data)) break;
  297.  
  298.   } while (de);
  299.  }
  300.  
  301.  /* Redraw list */
  302.  DoMethod(obj, MUIM_List_Redraw, MUIV_List_Redraw_All);
  303.  
  304.  /* Return 1 to indicate that the method is implemented */
  305.  return(1);
  306. }
  307.  
  308. /* EntryList class method: TMM_WBArg */
  309. #undef  DEBUGFUNCTION
  310. #define DEBUGFUNCTION EntryListClassWBArg
  311. static ULONG EntryListClassWBArg(Class *cl, Object *obj,
  312.                                  struct TMP_WBArg *tmpwa)
  313. {
  314.  Object *exec;
  315.  ULONG  rc    = 0;
  316.  
  317.  ENTRYLIST_LOG(LOG1(WBArg, "0x%08lx", tmpwa->tmpwa_Argument))
  318.  
  319.  /* Create exec object from WBArg */
  320.  if (exec = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_EXEC],
  321.                                  (Msg) tmpwa)) {
  322.   Object *image;
  323.  
  324.   ENTRYLIST_LOG(LOG1(Exec, "0x%08lx", exec))
  325.  
  326.   /* Create image object from WBArg */
  327.   if (image = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_IMAGE],
  328.                                    (Msg) tmpwa)) {
  329.    struct DockEntry  de;
  330.    struct AttachData ead;
  331.    struct AttachData iad;
  332.  
  333.    ENTRYLIST_LOG(LOG1(Image, "0x%08lx", image))
  334.  
  335.    /* Initialize dummy entry */
  336.    de.de_Exec  = &ead;
  337.    de.de_Image = &iad;
  338.    de.de_Sound = NULL;
  339.  
  340.    /* Initialize dummy attach data */
  341.    ead.ad_Object = exec;
  342.    iad.ad_Object = image;
  343.  
  344.    /* Insert "dummy" entry (it will be duplicated!) */
  345.    DoMethod(obj, MUIM_List_InsertSingle, &de, MUIV_List_Insert_Bottom);
  346.  
  347.    /* Return 1 to indicate success */
  348.    rc = 1;
  349.   }
  350.  }
  351.  
  352.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", rc))
  353.  
  354.  return(rc);
  355. }
  356.  
  357. /* EntryList class method: TMM_Column */
  358. #undef  DEBUGFUNCTION
  359. #define DEBUGFUNCTION EntryListClassColumn
  360. static ULONG EntryListClassColumn(Class *cl, Object *obj,
  361.                                   struct TMP_Column *tmpc)
  362. {
  363.  struct DockEntry  *de;
  364.  struct AttachData *ad = NULL;
  365.  
  366.  ENTRYLIST_LOG(LOG1(Column, "%ld", tmpc->tmpc_Column))
  367.  
  368.  /* Get active entry from list*/
  369.  DoMethod(obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &de);
  370.  
  371.  ENTRYLIST_LOG(LOG1(Entry, "0x%08lx", de))
  372.  
  373.  /* Select object to edit */
  374.  switch (tmpc->tmpc_Column) {
  375.   case 0: ad = de->de_Exec;  break;
  376.   case 1: ad = de->de_Image; break;
  377.   case 2: ad = de->de_Sound; break;
  378.  }
  379.  
  380.  ENTRYLIST_LOG(LOG1(Attach data, "0x%08lx", ad))
  381.  
  382.  /* Call edit method on the object */
  383.  if (ad) DoMethod(ad->ad_Object, TMM_Edit, NULL);
  384.  
  385.  /* Return 1 to indicate that the method is implemented */
  386.  return(1);
  387. }
  388.  
  389. /* EntryList class method dispatcher */
  390. #undef  DEBUGFUNCTION
  391. #define DEBUGFUNCTION EntryListClassDispatcher
  392. __geta4 static ULONG EntryListClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  393.                                               __a1 Msg msg)
  394. {
  395.  ULONG rc;
  396.  
  397. #if DEBUG_VERY_NOISY
  398.  /* This just generates too much debug output... */
  399.  ENTRYLIST_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  400.                     cl, obj, msg))
  401. #endif
  402.  
  403.  switch(msg->MethodID) {
  404.   /* BOOPSI methods */
  405.   case OM_NEW:
  406.    rc = EntryListClassNew(cl, obj, (struct opSet *) msg);
  407.    break;
  408.  
  409.   /* MUI methods */
  410.   case MUIM_DragQuery:
  411.    rc = EntryListClassDragQuery(cl, obj, (struct MUIP_DragQuery *) msg);
  412.    break;
  413.  
  414.   case MUIM_DragDrop:
  415.    rc = EntryListClassDragDrop(cl, obj, (struct MUIP_DragDrop *) msg);
  416.    break;
  417.  
  418.   /* TM methods */
  419.   case TMM_Notify:
  420.    rc = EntryListClassNotify(cl, obj, (struct TMP_Notify *) msg);
  421.    break;
  422.  
  423.   case TMM_WBArg:
  424.    rc = EntryListClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  425.    break;
  426.  
  427.   case TMM_Column:
  428.    rc = EntryListClassColumn(cl, obj, (struct TMP_Column *) msg);
  429.    break;
  430.  
  431.   /* Unknown method -> delegate to SuperClass */
  432.   default:
  433.    rc = DoSuperMethodA(cl, obj, msg);
  434.    break;
  435.  }
  436.  
  437.  return(rc);
  438. }
  439.  
  440. /* Create EntryList class */
  441. #undef  DEBUGFUNCTION
  442. #define DEBUGFUNCTION CreateEntryListClass
  443. struct MUI_CustomClass *CreateEntryListClass(void)
  444. {
  445.  struct MUI_CustomClass *rc;
  446.  
  447.  /* Create class */
  448.  if (rc = MUI_CreateCustomClass(NULL, MUIC_List, NULL,
  449.                                 sizeof(struct EntryListClassData),
  450.                                 EntryListClassDispatcher)) {
  451.  
  452.   /* Localize strings */
  453.   TextColumnExec  = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_EXEC_STR,
  454.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_EXEC);
  455.   TextColumnImage = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_IMAGE_STR,
  456.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_IMAGE);
  457.   TextColumnSound = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_SOUND_STR,
  458.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_SOUND);
  459.  }
  460.  
  461.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", rc))
  462.  
  463.  return(rc);
  464. }
  465.